package cate.game.activity.hangdrop.po;

import cate.common.table.activity.hangdrop.common.HangDropActivityCommonRow;
import cate.common.table.activity.hangdrop.exchange.HangDropActivityExchangeRow;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDObj;
import cate.common.util.GameResult;
import cate.game.activity.base.core.SubActivitySingle;
import cate.game.activity.hangdrop.HangDropActivity;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

@NoteClass("限时兑换-兑换数据")
public class HangDropExchangePO extends SubActivitySingle<HangDropActivity> {
    @NoteField("配置ID => 已兑换次数")
    public Map<Integer, Integer> exchangeRecords;

    @Override
    public void initialize(HangDropActivity parent) {
        super.initialize(parent);
        if (exchangeRecords == null) {
            exchangeRecords = new HashMap<>();
        }
    }

    public void excelCheck() {
        Map<Integer, HangDropActivityExchangeRow> configs = getExchangeConfigs();
        if (configs == null || configs.isEmpty()) {
            exchangeRecords.clear();
            return;
        }
        exchangeRecords.entrySet().removeIf(kv -> !configs.containsKey(kv.getKey()));
        for (HangDropActivityExchangeRow config : configs.values()) {
            if (!exchangeRecords.containsKey(config.id)) {
                exchangeRecords.put(config.id, 0);
            }
        }
    }

    public void clear() {
        exchangeRecords.clear();
    }

    public int configGroup() {
        return parent.getGroup();
    }

    /**
     * 获取兑换配置
     */
    @JsonIgnore
    public HangDropActivityExchangeRow getExchangeConfig(int tid) {
        switch (funcId()) {
            case GDFunc.ACT_HANG_DROP:
                return role.getGame().table.hangDropActivity.exchange.get(tid);
            default:
                return null;
        }
    }

    /**
     * 获取全部兑换配置
     */
    @JsonIgnore
    public Map<Integer, HangDropActivityExchangeRow> getExchangeConfigs() {
        Map<Integer, HangDropActivityExchangeRow> ret = new HashMap<>();
        switch (funcId()) {
            case GDFunc.ACT_HANG_DROP: {
                for (HangDropActivityExchangeRow config : role.getGame().table.hangDropActivity.exchange.getList()) {
                    if (config.group == configGroup()) {
                        ret.put(config.id, config);
                    }
                }
            }
            break;
        }
        return ret;
    }

    /**
     * 兑换奖励
     *
     * @param tid 配置ID
     * @param num 兑换数量
     * @return 兑换结果 无携带数据
     */
    public GameResult<Void> doExchange(int tid, int num) {
        GameResult<Void> r = new GameResult<>();
        if (num <= 0) {
            return r.fail("数量不合法");
        }
        if (!exchangeRecords.containsKey(tid)) {
            return r.fail("找不到配置1");
        }
        HangDropActivityExchangeRow config = getExchangeConfig(tid);
        if (config == null) {
            return r.fail("找不到配置2");
        }
        HangDropActivityCommonRow commonConfig = parent.getCommonConfig();
        if (commonConfig == null) {
            return r.fail("找不到配置3");
        }
        int curNum = exchangeRecords.get(tid);
        if (config.limit != -1 && num > config.limit - curNum) {
            return r.fail("兑换次数不足");
        }
        MixRes consumeRes = new MixRes(config.consumeStr);
        if (consumeRes.isEmpty()) {
            return r.fail("消耗配置错误");
        }
        consumeRes.items.forEach(item -> item.num *= num);
        MixRes rewardRes = new MixRes(config.rewardStr);
        if (rewardRes.isEmpty()) {
            return r.fail("奖励配置错误");
        }
        int materialCost = (int) consumeRes.count(GDObj.Type.PROP, commonConfig.dropItemId);
        consumeRes.items.removeIf(item -> item.type == GDObj.Type.PROP && item.tid == commonConfig.dropItemId);
        if (!consumeRes.isEmpty()) {
            role.log.setOperation(parent.getGDOperation(), tid);
            EcResult<?> r_res = consumeRes.consume(role);
            role.log.clearOperation();
            if (!r_res.ok()) {
                return r.fail(r_res.message);
            }
        }
        if (materialCost > 0) {
            EcResult<Void> r_material = parent.changeMaterialsNum(-materialCost, true);
            if (!r_material.ok()) {
                return r.fail(r_material.message);
            }
        }
        exchangeRecords.put(tid, curNum + num);
        rewardRes.items.forEach(item -> item.num *= num);
        EcResult exe = new MixResAdder().setRes(rewardRes)
                .setOperation(parent.getGDOperation())
                .setOperationSub(tid)
                .setSendMailWhenFull(true)
                .setDialogReward(true)
                .exe(role);
        return r.success();
    }
}
